import { OnInit, Component, Input, ViewChild } from '@angular/core';
import {
  NzModalRef,
  NzFormatEmitEvent,
  NzTreeComponent,
  NzMessageService,
  NzDrawerRef,
  NzNotificationService,
} from 'ng-zorro-antd';
import { _HttpClient } from '@delon/theme';
import { SFSchema, SFComponent, SFTreeSelectWidgetSchema } from '@delon/form';
import { catchError, delay, map } from 'rxjs/operators';
import { of, zip, Observable } from 'rxjs';
import { replaceKeysDeep } from '@shared';
import { HttpClient } from '@angular/common/http';

/**
 * 添加/编辑用户信息
 */
@Component({
  selector: 'user-info-modal',
  templateUrl: './user-modal.component.html',
})
export class UserInfoModalComponent implements OnInit {
  @Input()
  record: { [key: string]: any } = {};
  /**
   * 存放部门节点
   */
  nodes = [];
  // 节点树映射
  mapShortToLong = {
    id: 'key',
    name: 'title',
  };
  roles = [];
  @ViewChild('sf', { static: false }) sf: SFComponent;
  schema: SFSchema = { properties: {} };
  loading = false;
  constructor(
    public http: _HttpClient,
    private msg: NzMessageService,
    private ref: NzDrawerRef,
    private notice: NzNotificationService,
  ) {}

  ngOnInit() {
    this.loadDeptTreeAndRoles();
  }

  initEditSchema(userData) {
    this.schema = {
      properties: {
        userId: {
          type: 'string',
          title: '用户id',
          default: userData.userId,
          ui: { hidden: true },
        },
        username: {
          type: 'string',
          title: '账号',
          default: userData.username,
          readOnly: true,
        },
        name: {
          type: 'string',
          title: '用户名',
          default: userData.name,
        },
        role: {
          type: 'string',
          title: '角色',
          enum: this.roles,
          default: userData.roleList.map(r => r.roleId),
          ui: {
            widget: 'select',
            mode: 'multiple',
            maxTagCount: 3,
            allowClear: true,
          },
        },
        deptId: {
          type: 'string',
          title: '所属部门',
          enum: this.nodes,
          default: userData.deptId,
          ui: {
            widget: 'sf-tree-select2',
            allowClear: true,
            showSearch: true,
          },
        },
        phone: {
          type: 'string',
          title: '手机号',
          format: 'mobile',
          default: userData.phone,
          ui: {
            hidden: true,
          },
        },
        lockFlag: {
          type: 'boolean',
          title: '是否锁定',
          default: userData.lockFlag === '0' ? false : true,
          ui: {
            checkedChildren: '锁定',
            unCheckedChildren: '正常',
          },
        },
      },
      required: ['username', 'password', 'deptId', 'role'],
    };
  }

  /**
   * 初始化表单
   */
  initSchema() {
    this.schema = {
      properties: {
        userId: {
          type: 'string',
          title: '用户id',
          ui: { hidden: true },
        },
        username: {
          type: 'string',
          title: '账号',
          description: '默认以1111作为初始密码',
          ui: {
            validator: (value: any) =>
              this.http
                .get(`/cf/admin/user/details/${value}`)
                .pipe(map(res => (res.data ? [{ keyword: 'required', message: '用户名已存在' }] : []))),
          },
        },
        name: {
          type: 'string',
          title: '用户名',
        },
        password: {
          type: 'string',
          title: '密码',
          description: '不填写将以默认1111作为初始密码',
          ui: {
            hidden: true,
            type: 'password',
          },
        },
        role: {
          type: 'string',
          title: '角色',
          enum: this.roles,
          ui: {
            widget: 'select',
            mode: 'multiple',
            maxTagCount: 3,
            allowClear: true,
          },
        },
        deptId: {
          type: 'string',
          title: '所属部门',
          enum: this.nodes,
          ui: {
            widget: 'sf-tree-select2',
            allowClear: true,
            showSearch: true,
          },
        },
        phone: {
          type: 'string',
          title: '手机号',
          format: 'mobile',
          ui: {
            hidden: true,
          },
        },
        lockFlag: {
          type: 'boolean',
          title: '是否锁定',
          default: false,
          ui: {
            checkedChildren: '锁定',
            unCheckedChildren: '正常',
          },
        },
      },
      required: ['username', 'deptId', 'role'],
    };
  }

  /**
   * 加载部门树及角色列表
   */
  loadDeptTreeAndRoles() {
    const api = [this.http.get(`/cf/admin/dept/tree`), this.http.get(`/cf/admin/role/list`)];
    // 编辑
    if (this.record.userId) {
      api.push(this.http.get(`/cf/admin/user/${this.record.userId}`));
    }
    zip(...api)
      .pipe(
        catchError(([deptTree, roleList, userData]) => {
          return [deptTree, roleList, userData];
        }),
      )
      .subscribe(([deptTree, roleList, userData]) => {
        if (deptTree.status === 200) {
          this.nodes = [];
          const o: [] = replaceKeysDeep(deptTree.data, this.mapShortToLong);
          o.forEach(r => {
            this.nodes.push(r);
          });
        }
        if (roleList.status === 200) {
          this.roles = [];
          roleList.data.forEach(r => {
            this.roles.push({ label: r.roleName, value: r.roleId });
          });
        }
        if (this.record.userId) {
          this.initEditSchema(userData.data);
        } else {
          this.initSchema();
        }
      });
  }

  submit(value) {
    value.lockFlag = value.lockFlag ? '1' : '0';
    this.loading = true;
    const obs: Observable<string> = this.record.userId
      ? this.http.put(`/cf/admin/user`, value)
      : this.http.post(`/cf/admin/user`, value);
    obs.pipe(catchError(err => of(err))).subscribe(
      res => {
        this.loading = false;
        if (res.status === 200) {
          this.notice.success('成功', '保存成功');
          this.close(true);
        }
      },
      () => {},
      () => {
        this.loading = false;
      },
    );
  }

  close(ret = false) {
    if (ret) {
      this.ref.close(ret);
    } else {
      this.ref.close();
    }
  }
}
